package com.example.hosptial.service.impl;

import com.example.hosptial.model.enity.Doctor;
import com.example.hosptial.model.enity.Patient;
import com.example.hosptial.model.view.WardBedPatientView;
import com.example.hosptial.model.view.WardStatusView;
import com.example.hosptial.repository.DoctorRepository;
import com.example.hosptial.repository.PatientRepository;
import com.example.hosptial.repository.WardBedPatientViewRepository;
import com.example.hosptial.repository.WardStatusRepository;
import com.example.hosptial.service.AdmissionService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

@Service
public class AdmissionServiceImpl implements AdmissionService {
    private static final Logger logger = LoggerFactory.getLogger(AdmissionServiceImpl.class);

    @Autowired
    private WardStatusRepository wardStatusRepository;

    @Autowired
    private WardBedPatientViewRepository wardBedPatientViewRepository;

    @Autowired
    private PatientRepository patientRepository;

    @Autowired
    private DoctorRepository doctorRepository;

    private static final int BED_STATUS_AVAILABLE = 2;

    @Override
    public List<Integer> getFloorsByDepartment(Integer deptId) {
        return wardStatusRepository.findDistinctFloorNumByDeptId(deptId);
    }

    @Override
    public List<WardStatusView> getAvailableWardsByFloorAndDept(Integer deptId, Integer floorNum) {
        return wardStatusRepository.findByDeptIdAndFloorNumAndAvailableBedsGreaterThan(deptId, floorNum, 0);
    }

    @Override
    public List<WardBedPatientView> getAvailableBedsByWard(Integer wardId) {
        return wardBedPatientViewRepository.findByWardIdAndBedStatus(wardId, BED_STATUS_AVAILABLE);
    }

    @Override
    @Transactional
    public void admitPatient(String patientName, String patientGender, Integer patientAge,
                           String patientIdCard, String patientPhone, String conditionDesc,
                           String doctorId, Integer bedId) {
        try {
            // 检查床位是否可用
            List<WardBedPatientView> availableBeds = wardBedPatientViewRepository.findByWardIdAndBedStatus(
                wardBedPatientViewRepository.findById(bedId).get().getWardId(),
                BED_STATUS_AVAILABLE
            );
            
            boolean bedAvailable = availableBeds.stream()
                .anyMatch(bed -> bed.getBedId().equals(bedId));
                
            if (!bedAvailable) {
                throw new IllegalStateException("选择的床位已被占用，请刷新页面重新选择");
            }

            // 检查身份证是否已存在
            if (patientRepository.findAll().stream()
                    .anyMatch(p -> p.getPatientIdCard().equals(patientIdCard))) {
                throw new IllegalStateException("该身份证号已存在，不能重复入院");
            }

            // 调用存储过程办理入院
            patientRepository.admitPatient(
                patientName,
                patientGender,
                patientAge,
                patientIdCard,
                patientPhone,
                conditionDesc,
                doctorId,
                bedId
            );
            
            logger.info("病人 {} 入院办理成功", patientName);
        } catch (IllegalStateException e) {
            logger.warn("入院办理失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("入院办理失败: {}", e.getMessage(), e);
            throw new IllegalStateException("入院办理失败，请检查输入信息或稍后重试");
        }
    }

    @Override
    @Transactional
    public void dischargePatient(Integer patientId, String doctorId) {
        if (patientId == null || patientId <= 0) {
            throw new IllegalArgumentException("无效的病人ID");
        }

        if (doctorId == null || doctorId.trim().isEmpty()) {
            throw new IllegalArgumentException("医生ID不能为空");
        }

        // 验证医生权限
        if (!validateDoctorAuthority(patientId, doctorId)) {
            throw new SecurityException("没有权限为该病人办理出院");
        }

        // 调用存储过程办理出院
        patientRepository.dischargePatient(patientId);
        logger.info("病人 {} 出院办理成功", patientId);
    }

    @Override
    public boolean validateDoctorAuthority(Integer patientId, String doctorId) {
        Patient patient = patientRepository.findById(patientId)
            .orElseThrow(() -> new IllegalArgumentException("病人不存在"));

        // 验证该病人是否是这个医生的病人
        return patient.getDoctor() != null &&
               patient.getDoctor().getDoctorId().equals(doctorId);
    }

}